`include "chunjun_define.sv" 
`include "chunjun_lib_define.sv" 
 
//================================================================================================
// File Name   : chunjun_tcu_dtcmarb.sv
// Create Time : Wed Nov  6 14:59:06 2024
// Description : Arbiter for DTCM 
//================================================================================================
 
//接收各个master的请求，仲裁出lo bank和hi bank的请求
module chunjun_tcu_dtcmarb #(
  parameter ID_W       = 7 ,
  parameter RAM_DATA_W = 32,
  parameter WDATA_W    = 2 * RAM_DATA_W,  // cannot modify
  parameter ATOP_EN    = 0                // atomic switch
)(
input  logic                    clk              ,
input  logic                    rst_n            ,
 
// icu <-> dtcm
input  logic                    icu_dtcm_req_vld ,   //icu的请求有效
output logic                    dtcm_icu_req_rdy ,   //icu的请求被接受
input  logic [19:0]             icu_dtcm_req_addr,   //icu的请求地址
input  logic [ID_W-1:0]         icu_dtcm_req_id  ,   //icu的请求id
 
// lsu <-> dtcm
input  logic [1:0]              lsu_dtcm_req_vld ,   //lsu的请求有效
output logic [1:0]              dtcm_lsu_req_rdy ,   //lsu的请求被接受
input  logic [1:0][19:0]        lsu_dtcm_req_addr,   //lsu的请求地址
input  logic [1:0][ID_W-1:0]    lsu_dtcm_req_id  ,   //lsu的请求id

// sbu <-> dtcm
input  logic                    sbu_dtcm_req_vld  ,  //sbu的请求有效
output logic                    dtcm_sbu_req_rdy  ,  //sbu的请求被接受
input  logic [19:0]             sbu_dtcm_req_addr ,  //sbu的请求地址
input  logic [ID_W-1:0]         sbu_dtcm_req_id   ,  //sbu的请求id
input  logic [WDATA_W-1:0]      sbu_dtcm_req_wdata,  //sbu的请求写数据
input  logic [ 7:0]             sbu_dtcm_req_wstrb,  //sbu的请求写使能
input  logic [ 5:0]             sbu_dtcm_req_atop ,  //sbu的请求地址[2]为0时，选择sbu_dtcm_req_atop

// slv <-> dtcm
input  logic                    slv_dtcm_req_vld  ,  //slv的请求有效
output logic                    dtcm_slv_req_rdy  ,  //slv的请求被接受
input  logic [19:0]             slv_dtcm_req_addr ,  //slv的请求地址
input  logic [ID_W-1:0]         slv_dtcm_req_id   ,  //slv的请求id
input  logic                    slv_dtcm_req_wr   ,  //slv的请求写使能
input  logic [WDATA_W-1:0]      slv_dtcm_req_wdata,  //slv的请求写数据
input  logic [ 7:0]             slv_dtcm_req_wstrb,  //slv的请求写使能

// vpu <-> dtcm
input  logic [1:0]              vpu_dtcm_req_vld ,  //vpu的请求有效
output logic [1:0]              dtcm_vpu_req_rdy ,  //vpu的请求被接受
input  logic [1:0][19:0]        vpu_dtcm_req_addr,  //vpu的请求地址
input  logic [1:0][ID_W-1:0]    vpu_dtcm_req_id  ,  //vpu的请求id
 
// ram_lo <-> dtcm
output logic                    bank_lo_vld   ,  //ram_lo的请求有效
input  logic                    bank_lo_rdy   ,  //ram_lo的请求被接受
output logic [19:0]             bank_lo_addr  ,  //ram_lo的请求地址
output logic [ID_W-1:0]         bank_lo_id    ,  //ram_lo的请求id
output logic                    bank_lo_wr    ,  //ram_lo的请求写使能
output logic [RAM_DATA_W-1:0]   bank_lo_wdata ,  //ram_lo的请求写数据
output logic [3:0]              bank_lo_wstrb ,  //ram_lo的请求写使能
output logic [5:0]              bank_lo_atop  ,  //ram_lo的请求地址[2]为0时，选择sbu_dtcm_req_atop

// ram_hi <-> dtcm
output logic                    bank_hi_vld   ,  //ram_hi的请求有效
input  logic                    bank_hi_rdy   ,  //ram_hi的请求被接受
output logic [19:0]             bank_hi_addr  ,  //ram_hi的请求地址
output logic [ID_W-1:0]         bank_hi_id    ,  //ram_hi的请求id
output logic                    bank_hi_wr    ,  //ram_hi的请求写使能
output logic [RAM_DATA_W-1:0]   bank_hi_wdata ,  //ram_hi的请求写数据
output logic [3:0]              bank_hi_wstrb ,  //ram_hi的请求写使能
output logic [5:0]              bank_hi_atop  ,  //ram_hi的请求地址[2]为0时，选择sbu_dtcm_req_atop

input  logic                    bank_lo_busy  ,  //ram_lo忙
input  logic                    bank_hi_busy    //ram_hi忙
);

//=================================================================================
// Arch Description
//=================================================================================

// * ldxb: DTCM load xbar.
//         Exchange dual-issue load to DTCM low-bank/high-bank request pair. 
//
// * vxb:  DTCM V-load xbar
//         Exchange dual-issue VPU load to DTCM low-bank/high-bank request pair.
//
// * parb: DTCM pre arbiter.
//         Arbitrate ICU/SBU/SLV-Bus request which access both low-bank/high-bank.
//
// * darb: DTCM main arbiter.
//         Arbitrate lo/hi bank request pair from ldxb and parb.
//         The lo/hi bank requests from parb must get arbitration at the same time in darb.

// -----------      -----------      -----------
// |  ldxb   |      |  parb   |      |   vxb   |
// -----------      -----------      -----------
// lo |  | hi       lo |  | hi       lo |   | hi
//    |  |             |  |             |   |
// ---------------------------------------------
// |                   darb                    |
// ---------------------------------------------
//            lo |               | hi
//          -----------      -----------
//          | lo bank |      | hi bank |
//          -----------      -----------

//=================================================================================
// Local Parameters
//=================================================================================

// Pre-arbiter fixed priority order: LSB > MSB.
// SBU > SLV > ICU
localparam MUX_PARB_SBU = 0;
localparam MUX_PARB_SLV = 1;
localparam MUX_PARB_ICU = 2;

localparam MUX_DARB_LDXB = 0;
localparam MUX_DARB_PARB = 1;
localparam MUX_DARB_VXB  = 2;
 
//=================================================================================
// Local Variables 
//=================================================================================

logic [1:0]                 ldxb_lo_req; //ldxb的低位请求
logic [1:0]                 ldxb_hi_req; //ldxb的高位请求
logic [1:0]                 ldxb_lo_grt; //ldxb的低位请求被选中
logic [1:0]                 ldxb_hi_grt; //ldxb的高位请求被选中
logic [19:0]                ldxb_darb_lo_req_addr; //ldxb的低位请求地址
logic [ID_W-1:0]            ldxb_darb_lo_req_id  ; //ldxb的低位请求id
logic [19:0]                ldxb_darb_hi_req_addr; //ldxb的高位请求地址
logic [ID_W-1:0]            ldxb_darb_hi_req_id  ; //ldxb的高位请求id
 
logic [2:0]                 parb_req; //pre-arb的请求
logic [2:0][19:0]           parb_req_addr; //pre-arb的请求地址
logic [2:0][ID_W-1:0]       parb_req_id  ; //pre-arb的请求id
logic [2:0]                 parb_req_wr  ; //pre-arb的请求写使能
logic [2:0][WDATA_W-1:0]    parb_req_wdata; //pre-arb的请求写数据
logic [2:0][7:0]            parb_req_wstrb; //pre-arb的请求写使能
logic [2:0]                 parb_grt; //pre-arb的请求被选中
logic                       parb_darb_req_vld  ; //pre-arb的请求有效
logic                       parb_darb_req_atop ; //pre-arb的请求地址[2]为0时，选择sbu_dtcm_req_atop
logic [19:0]                parb_darb_req_addr ; //pre-arb的请求地址
logic [ID_W-1:0]            parb_darb_req_id   ; //pre-arb的请求id
logic                       parb_darb_req_wr   ; //pre-arb的请求写使能
logic [WDATA_W-1:0]         parb_darb_req_wdata; //pre-arb的请求写数据
logic [7:0]                 parb_darb_req_wstrb; //pre-arb的请求写使能
 
logic [1:0]                 vxb_lo_req; //vxb的低位请求
logic [1:0]                 vxb_hi_req; //vxb的高位请求
logic [1:0]                 vxb_lo_grt; //vxb的低位请求被选中
logic [1:0]                 vxb_hi_grt; //vxb的高位请求被选中
logic [19:0]                vxb_darb_lo_req_addr; //vxb的低位请求地址
logic [19:0]                vxb_darb_hi_req_addr; //vxb的高位请求地址
logic [ID_W-1:0]            vxb_darb_lo_req_id  ; //vxb的低位请求id
logic [ID_W-1:0]            vxb_darb_hi_req_id  ; //vxb的高位请求id



logic [2:0][19:0]           darb_lo_req_addr; //仲裁的低位请求地址
logic [2:0][ID_W-1:0]       darb_lo_req_id  ; //仲裁的低位请求id
logic [2:0]                 darb_lo_req_wr  ; //仲裁的低位请求写使能
logic [2:0][19:0]           darb_hi_req_addr; //仲裁的高位请求地址
logic [2:0][ID_W-1:0]       darb_hi_req_id  ; //仲裁的高位请求id
logic [2:0]                 darb_hi_req_wr  ; //仲裁的高位请求写使能
logic [2:0]                 darb_req; //仲裁的请求
logic [2:0]                 darb_grt; //仲裁的请求被选中
logic                       darb_ldxb_lo_req_rdy; //ldxb的低位请求被选中且bank_lo_rdy为1时，请求被接受
logic                       darb_ldxb_hi_req_rdy; //ldxb的高位请求被选中且bank_hi_rdy为1时，请求被接受
logic                       darb_parb_req_rdy; //pre-arb的低位请求被选中且bank_lo_rdy和bank_hi_rdy为1时，请求被接受
logic                       darb_vxb_lo_req_rdy; //vxb的低位请求被选中且bank_lo_rdy为1时，请求被接受
logic                       darb_vxb_hi_req_rdy; //vxb的高位请求被选中且bank_hi_rdy为1时，请求被接受
logic                       dtcm_busy; //dtcm忙
 
assign dtcm_busy = bank_lo_busy | bank_hi_busy; //dtcm忙

//=================================================================================
// ld-xbar
//=================================================================================

assign ldxb_lo_req[0] = lsu_dtcm_req_vld[0] & ~lsu_dtcm_req_addr[0][2];  //当ld0有效 addr[2] = 0时，ld0访问低bank
assign ldxb_lo_req[1] = lsu_dtcm_req_vld[1] & ~lsu_dtcm_req_addr[1][2];  //当ld1有效 addr[2] = 0时，ld1访问低bank
  
assign ldxb_hi_req[0] = lsu_dtcm_req_vld[0] &  lsu_dtcm_req_addr[0][2];  //当ld0有效 addr[2] = 1时，ld0访问高bank
assign ldxb_hi_req[1] = lsu_dtcm_req_vld[1] &  lsu_dtcm_req_addr[1][2];  //当ld1有效 addr[2] = 1时，ld1访问高bank

// Fixed priority from LSB to MSB.
// 从LSB（最低位）到MSB（最高位）查找第一个1
//选择优先级最高ld0的请求的放在低位

wing_cbb_priority_queue #(.MODE(0), .WIDTH(2), .LOCK(0)) u_ff1_ldxb_lo (.clk(clk), .rst_n(rst_n), .lock(1'b0), .vec_i(ldxb_lo_req), .onehot_o(ldxb_lo_grt)); //仲裁出lo bank的请求
wing_cbb_priority_queue #(.MODE(0), .WIDTH(2), .LOCK(0)) u_ff1_ldxb_hi (.clk(clk), .rst_n(rst_n), .lock(1'b0), .vec_i(ldxb_hi_req), .onehot_o(ldxb_hi_grt)); //仲裁出hi bank的请求

// Low-bank & High-bank request from ld-xbar to DTCM-arbiter.
//选择对应lo bank的地址和id
wing_cbb_aomux #(.NUM(2), .WIDTH(20  )) u_aomux_ldxb_lo_addr (.data_arr(lsu_dtcm_req_addr), .sel_in_onehot0(ldxb_lo_grt), .data_sel(ldxb_darb_lo_req_addr)); //选择对应lo bank的地址
wing_cbb_aomux #(.NUM(2), .WIDTH(ID_W)) u_aomux_ldxb_lo_id   (.data_arr(lsu_dtcm_req_id  ), .sel_in_onehot0(ldxb_lo_grt), .data_sel(ldxb_darb_lo_req_id  )); //选择对应lo bank的id

//选择对应hi bank的地址和id
wing_cbb_aomux #(.NUM(2), .WIDTH(20  )) u_aomux_ldxb_hi_addr (.data_arr(lsu_dtcm_req_addr), .sel_in_onehot0(ldxb_hi_grt), .data_sel(ldxb_darb_hi_req_addr)); //选择对应hi bank的地址
wing_cbb_aomux #(.NUM(2), .WIDTH(ID_W)) u_aomux_ldxb_hi_id   (.data_arr(lsu_dtcm_req_id  ), .sel_in_onehot0(ldxb_hi_grt), .data_sel(ldxb_darb_hi_req_id  )); //选择对应hi bank的id

// Request ready from ld-xbar to source interface.
 
assign dtcm_lsu_req_rdy[0] = ldxb_lo_grt[0] & darb_ldxb_lo_req_rdy | //ld0的低位请求被选中且bank_req_rdy_m1为1时，请求被接受
                             ldxb_hi_grt[0] & darb_ldxb_hi_req_rdy ; //ld0的高位请求被选中且bank_req_rdy_m1为1时，请求被接受

assign dtcm_lsu_req_rdy[1] = ldxb_lo_grt[1] & darb_ldxb_lo_req_rdy | //ld1的低位请求被选中且bank_req_rdy_m1为1时，请求被接受
                             ldxb_hi_grt[1] & darb_ldxb_hi_req_rdy ; //ld1的高位请求被选中且bank_req_rdy_m1为1时，请求被接受

//=================================================================================
// pre-arbiter
//=================================================================================

assign parb_req      [MUX_PARB_SBU] = sbu_dtcm_req_vld; //SBU请求有效
assign parb_req      [MUX_PARB_SLV] = slv_dtcm_req_vld; //SLV请求有效
assign parb_req      [MUX_PARB_ICU] = icu_dtcm_req_vld; //ICU请求有效

assign parb_req_addr [MUX_PARB_SBU] = sbu_dtcm_req_addr; //SBU请求地址
assign parb_req_addr [MUX_PARB_SLV] = slv_dtcm_req_addr; //SLV请求地址
assign parb_req_addr [MUX_PARB_ICU] = icu_dtcm_req_addr; //ICU请求地址

assign parb_req_id   [MUX_PARB_SBU] = sbu_dtcm_req_id; //SBU请求id
assign parb_req_id   [MUX_PARB_SLV] = slv_dtcm_req_id; //SLV请求id
assign parb_req_id   [MUX_PARB_ICU] = icu_dtcm_req_id; //ICU请求id

assign parb_req_wr   [MUX_PARB_SBU] = 1'b1; //SBU请求写使能
assign parb_req_wr   [MUX_PARB_SLV] = slv_dtcm_req_wr; //SLV请求写使能
assign parb_req_wr   [MUX_PARB_ICU] = 1'b0; //ICU请求写使能

assign parb_req_wdata[MUX_PARB_SBU] = sbu_dtcm_req_wdata; //SBU请求写数据
assign parb_req_wdata[MUX_PARB_SLV] = slv_dtcm_req_wdata; //SLV请求写数据
assign parb_req_wdata[MUX_PARB_ICU] = {WDATA_W{1'b0}}; //ICU请求写数据

assign parb_req_wstrb[MUX_PARB_SBU] = sbu_dtcm_req_wstrb;
assign parb_req_wstrb[MUX_PARB_SLV] = slv_dtcm_req_wstrb;
assign parb_req_wstrb[MUX_PARB_ICU] = 8'b0;

// Fixed priority from LSB to MSB.
 
wing_cbb_priority_queue #(.MODE(0), .WIDTH(3), .LOCK(0)) u_ff1_parb (.clk(clk), .rst_n(rst_n), .lock(1'b0), .vec_i(parb_req), .onehot_o(parb_grt));
 
// Low-bank & High-bank request from pre-arbiter to DTCM-arbiter.
 
// Opt -> sbu to dtcm bank request can be controlled precisely.
//        When sbu request is NOT partial_write or atop, we don't need to 
//        check dtcm_busy actually.
 
// All pre-arb requests access both lo/hi banks, even if SBU and SLV-BUS may access only one bank as per wstrb.
// The reason is to reduce critical timing path slack.

assign parb_darb_req_vld  = ~dtcm_busy & (|parb_req);  //如果dtcm_busy为0，且parb_req有请求，则parb_darb_req_vld为1
assign parb_darb_req_atop = parb_req[MUX_PARB_SBU] & (|sbu_dtcm_req_atop[5:4]); //如果parb_req的SBU请求有效，且sbu_dtcm_req_atop[5:4]不为0，则parb_darb_req_atop为1

wing_cbb_aomux #(.NUM(3), .WIDTH(20     )) u_aomux_parb_addr (.data_arr(parb_req_addr ), .sel_in_onehot0(parb_grt), .data_sel(parb_darb_req_addr ));
wing_cbb_aomux #(.NUM(3), .WIDTH(ID_W   )) u_aomux_parb_id   (.data_arr(parb_req_id   ), .sel_in_onehot0(parb_grt), .data_sel(parb_darb_req_id   ));
wing_cbb_aomux #(.NUM(3), .WIDTH(1      )) u_aomux_parb_wr   (.data_arr(parb_req_wr   ), .sel_in_onehot0(parb_grt), .data_sel(parb_darb_req_wr   ));
wing_cbb_aomux #(.NUM(3), .WIDTH(WDATA_W)) u_aomux_parb_wdata(.data_arr(parb_req_wdata), .sel_in_onehot0(parb_grt), .data_sel(parb_darb_req_wdata));
wing_cbb_aomux #(.NUM(3), .WIDTH(8      )) u_aomux_parb_wstrb(.data_arr(parb_req_wstrb), .sel_in_onehot0(parb_grt), .data_sel(parb_darb_req_wstrb));

// Request ready from pre-arbiter to source interface.
 
assign dtcm_sbu_req_rdy = parb_grt[MUX_PARB_SBU] & darb_parb_req_rdy; //如果parb_grt的SBU请求被选中，且darb_parb_req_rdy为1，则dtcm_sbu_req_rdy为1
assign dtcm_slv_req_rdy = parb_grt[MUX_PARB_SLV] & darb_parb_req_rdy; //如果parb_grt的SLV请求被选中，且darb_parb_req_rdy为1，则dtcm_slv_req_rdy为1
assign dtcm_icu_req_rdy = parb_grt[MUX_PARB_ICU] & darb_parb_req_rdy; //如果parb_grt的ICU请求被选中，且darb_parb_req_rdy为1，则dtcm_icu_req_rdy为1

//=================================================================================
// V-xbar
//=================================================================================

assign vxb_lo_req[0] = vpu_dtcm_req_vld[0] & ~vpu_dtcm_req_addr[0][2]; //当vpu0有效 addr[2] = 0时，vpu0访问低bank
assign vxb_lo_req[1] = vpu_dtcm_req_vld[1] & ~vpu_dtcm_req_addr[1][2]; //当vpu1有效 addr[2] = 0时，vpu1访问低bank
 
assign vxb_hi_req[0] = vpu_dtcm_req_vld[0] &  vpu_dtcm_req_addr[0][2]; //当vpu0有效 addr[2] = 1时，vpu0访问高bank
assign vxb_hi_req[1] = vpu_dtcm_req_vld[1] &  vpu_dtcm_req_addr[1][2]; //当vpu1有效 addr[2] = 1时，vpu1访问高bank

// Fixed priority from LSB to MSB.
// 从LSB（最低位）到MSB（最高位）查找第一个1
wing_cbb_priority_queue #(.MODE(0), .WIDTH(2), .LOCK(0)) u_ff1_vxb_lo (.clk(clk), .rst_n(rst_n), .lock(1'b0), .vec_i(vxb_lo_req), .onehot_o(vxb_lo_grt));
wing_cbb_priority_queue #(.MODE(0), .WIDTH(2), .LOCK(0)) u_ff1_vxb_hi (.clk(clk), .rst_n(rst_n), .lock(1'b0), .vec_i(vxb_hi_req), .onehot_o(vxb_hi_grt));

// Low-bank & High-bank request from ld-xbar to DTCM-arbiter.
 //选择对应lo bank的地址和id
wing_cbb_aomux #(.NUM(2), .WIDTH(20  )) u_aomux_vxb_lo_addr (.data_arr(vpu_dtcm_req_addr), .sel_in_onehot0(vxb_lo_grt), .data_sel(vxb_darb_lo_req_addr));
wing_cbb_aomux #(.NUM(2), .WIDTH(ID_W)) u_aomux_vxb_lo_id   (.data_arr(vpu_dtcm_req_id  ), .sel_in_onehot0(vxb_lo_grt), .data_sel(vxb_darb_lo_req_id  ));

//选择对应hi bank的地址和id
wing_cbb_aomux #(.NUM(2), .WIDTH(20  )) u_aomux_vxb_hi_addr (.data_arr(vpu_dtcm_req_addr), .sel_in_onehot0(vxb_hi_grt), .data_sel(vxb_darb_hi_req_addr));
wing_cbb_aomux #(.NUM(2), .WIDTH(ID_W)) u_aomux_vxb_hi_id   (.data_arr(vpu_dtcm_req_id  ), .sel_in_onehot0(vxb_hi_grt), .data_sel(vxb_darb_hi_req_id  ));

// Request ready from ld-xbar to source interface.
 
assign dtcm_vpu_req_rdy[0] = vxb_lo_grt[0] & darb_vxb_lo_req_rdy | //vpu0的低位请求被选中且bank_req_rdy_m1为1时，请求被接受
                             vxb_hi_grt[0] & darb_vxb_hi_req_rdy ; //vpu0的高位请求被选中且bank_req_rdy_m1为1时，请求被接受

assign dtcm_vpu_req_rdy[1] = vxb_lo_grt[1] & darb_vxb_lo_req_rdy | //vpu1的低位请求被选中且bank_req_rdy_m1为1时，请求被接受
                             vxb_hi_grt[1] & darb_vxb_hi_req_rdy ; //vpu1的高位请求被选中且bank_req_rdy_m1为1时，请求被接受

//=================================================================================
// DTCM Arbiter
//=================================================================================

// ldxb
assign darb_lo_req_addr [MUX_DARB_LDXB] = ldxb_darb_lo_req_addr; //ldxb的低位请求地址
assign darb_lo_req_id   [MUX_DARB_LDXB] = ldxb_darb_lo_req_id  ; //ldxb的低位请求id
assign darb_lo_req_wr   [MUX_DARB_LDXB] = 1'b0; //ldxb的低位请求写使能

assign darb_hi_req_addr [MUX_DARB_LDXB] = ldxb_darb_hi_req_addr; //ldxb的高位请求地址
assign darb_hi_req_id   [MUX_DARB_LDXB] = ldxb_darb_hi_req_id  ; //ldxb的高位请求id
assign darb_hi_req_wr   [MUX_DARB_LDXB] = 1'b0; //ldxb的高位请求写使能

// pre-arb
assign darb_lo_req_addr [MUX_DARB_PARB] = parb_darb_req_addr ; //pre-arb的低位请求地址
assign darb_lo_req_id   [MUX_DARB_PARB] = parb_darb_req_id   ; //pre-arb的低位请求id
assign darb_lo_req_wr   [MUX_DARB_PARB] = parb_darb_req_wr   ; //pre-arb的低位请求写使能

assign darb_hi_req_addr [MUX_DARB_PARB] = {parb_darb_req_addr[19:3],3'b100} ; //pre-arb的高位请求地址
assign darb_hi_req_id   [MUX_DARB_PARB] = parb_darb_req_id   ; //pre-arb的高位请求id
assign darb_hi_req_wr   [MUX_DARB_PARB] = parb_darb_req_wr   ; //pre-arb的高位请求写使能

// vxb
assign darb_lo_req_addr [MUX_DARB_VXB] = vxb_darb_lo_req_addr; //vxb的低位请求地址
assign darb_lo_req_id   [MUX_DARB_VXB] = vxb_darb_lo_req_id  ; //vxb的低位请求id
assign darb_lo_req_wr   [MUX_DARB_VXB] = 1'b0; //vxb的低位请求写使能

assign darb_hi_req_addr [MUX_DARB_VXB] = vxb_darb_hi_req_addr; //vxb的高位请求地址
assign darb_hi_req_id   [MUX_DARB_VXB] = vxb_darb_hi_req_id  ; //vxb的高位请求id
assign darb_hi_req_wr   [MUX_DARB_VXB] = 1'b0; //vxb的高位请求写使能

// - When parb_req access both low-bank and high-bank, we must grant parb
//   at the same time.
// - (Deprecated) When parb_req access only one bank (either low-bank or high-bank), each bank
//                grant separately, i.e., situation that low-bank grants to ldxb and 
//                high-bank grants to parb is allowed.
 
// Fixed priority arbiter.
// load > pre-arbiter > v-load

assign darb_req[MUX_DARB_LDXB] = |lsu_dtcm_req_vld; //ldxb请求有效
assign darb_req[MUX_DARB_PARB] = parb_darb_req_vld; //pre-arb请求有效
assign darb_req[MUX_DARB_VXB]  = |vpu_dtcm_req_vld; //vxb请求有效

assign darb_grt[MUX_DARB_LDXB] = darb_req[MUX_DARB_LDXB]; //ldxb请求被选中
assign darb_grt[MUX_DARB_PARB] = darb_req[MUX_DARB_PARB] & ~darb_req[MUX_DARB_LDXB]; //pre-arb请求被选中
assign darb_grt[MUX_DARB_VXB]  = darb_req[MUX_DARB_VXB]  & ~darb_req[MUX_DARB_PARB] & ~darb_req[MUX_DARB_LDXB]; //vxb请求被选中
 
// Low-bank & High-bank request from DTCM-arbiter to interface.
 
assign bank_lo_vld = darb_grt[MUX_DARB_LDXB] & (|ldxb_lo_req) //ldxb的低位请求被选中
                   | darb_grt[MUX_DARB_PARB] & (parb_darb_req_atop ? (~parb_darb_req_addr[2]) : 1'b1) //pre-arb的低位请求被选中
                   | darb_grt[MUX_DARB_VXB]  & (|vxb_lo_req) ; //vxb的低位请求被选中

assign bank_hi_vld = darb_grt[MUX_DARB_LDXB] & (|ldxb_hi_req) //ldxb的高位请求被选中
                   | darb_grt[MUX_DARB_PARB] & (parb_darb_req_atop ? (parb_darb_req_addr[2]) : 1'b1) //pre-arb的高位请求被选中
                   | darb_grt[MUX_DARB_VXB]  & (|vxb_hi_req); //vxb的高位请求被选中

wing_cbb_aomux #(.NUM(3), .WIDTH(20  )) u_aomux_darb_lo_addr (.data_arr(darb_lo_req_addr), .sel_in_onehot0(darb_grt), .data_sel(bank_lo_addr )); //选择低位请求的地址
wing_cbb_aomux #(.NUM(3), .WIDTH(ID_W)) u_aomux_darb_lo_id   (.data_arr(darb_lo_req_id  ), .sel_in_onehot0(darb_grt), .data_sel(bank_lo_id   )); //选择低位请求的id
wing_cbb_aomux #(.NUM(3), .WIDTH(1   )) u_aomux_darb_lo_wr   (.data_arr(darb_lo_req_wr  ), .sel_in_onehot0(darb_grt), .data_sel(bank_lo_wr   )); //选择低位请求的写使能

wing_cbb_aomux #(.NUM(3), .WIDTH(20  )) u_aomux_darb_hi_addr (.data_arr(darb_hi_req_addr), .sel_in_onehot0(darb_grt), .data_sel(bank_hi_addr )); //选择高位请求的地址
wing_cbb_aomux #(.NUM(3), .WIDTH(ID_W)) u_aomux_darb_hi_id   (.data_arr(darb_hi_req_id  ), .sel_in_onehot0(darb_grt), .data_sel(bank_hi_id   )); //选择高位请求的id
wing_cbb_aomux #(.NUM(3), .WIDTH(1   )) u_aomux_darb_hi_wr   (.data_arr(darb_hi_req_wr  ), .sel_in_onehot0(darb_grt), .data_sel(bank_hi_wr   )); //选择高位请求的写使能

assign bank_lo_wdata = parb_darb_req_wdata[(WDATA_W/2)-1: 0]; //选择低位请求的写数据
assign bank_lo_wstrb = parb_darb_req_wstrb[ 3: 0]; //选择低位请求的写使能
assign bank_hi_wdata = parb_darb_req_wdata[WDATA_W-1:(WDATA_W/2)]; //选择高位请求的写数据
assign bank_hi_wstrb = parb_darb_req_wstrb[ 7: 4]; //选择高位请求的写使能
 
// Request ready from DTCM-arbiter to ld-xbar and pre-arbiter.

assign darb_ldxb_lo_req_rdy = darb_grt[MUX_DARB_LDXB] & bank_lo_rdy; //ldxb的低位请求被选中且bank_lo_rdy为1时，请求被接受
assign darb_ldxb_hi_req_rdy = darb_grt[MUX_DARB_LDXB] & bank_hi_rdy; //ldxb的高位请求被选中且bank_hi_rdy为1时，请求被接受
 
assign darb_parb_req_rdy = darb_grt[MUX_DARB_PARB] & bank_lo_rdy & bank_hi_rdy; //pre-arb的低位请求被选中且bank_lo_rdy和bank_hi_rdy为1时，请求被接受

assign darb_vxb_lo_req_rdy = darb_grt[MUX_DARB_VXB] & bank_lo_rdy; //vxb的低位请求被选中且bank_lo_rdy为1时，请求被接受
assign darb_vxb_hi_req_rdy = darb_grt[MUX_DARB_VXB] & bank_hi_rdy; //vxb的高位请求被选中且bank_hi_rdy为1时，请求被接受
 
if (ATOP_EN==1) begin : EN_ATOP

// sbu_dtcm_req_wstrb is always aligned with sbu_dtcm_req_addr[2].

assign bank_lo_atop = {6{darb_grt[MUX_DARB_PARB] & parb_grt[MUX_PARB_SBU] & ~sbu_dtcm_req_addr[2]}} & sbu_dtcm_req_atop; //pre-arb的低位请求被选中且parb_grt的SBU请求被选中且sbu_dtcm_req_addr[2]为0时，选择sbu_dtcm_req_atop
assign bank_hi_atop = {6{darb_grt[MUX_DARB_PARB] & parb_grt[MUX_PARB_SBU] &  sbu_dtcm_req_addr[2]}} & sbu_dtcm_req_atop; //pre-arb的高位请求被选中且parb_grt的SBU请求被选中且sbu_dtcm_req_addr[2]为1时，选择sbu_dtcm_req_atop

end else begin : NO_ATOP
 
assign bank_lo_atop = 6'b0; //pre-arb的低位请求被选中且parb_grt的SBU请求被选中且sbu_dtcm_req_addr[2]为0时，选择sbu_dtcm_req_atop
assign bank_hi_atop = 6'b0; //pre-arb的高位请求被选中且parb_grt的SBU请求被选中且sbu_dtcm_req_addr[2]为1时，选择sbu_dtcm_req_atop

end // ATOP_EN
 
//=================================================================================
// Assertion
//=================================================================================
 
 
endmodule
`include "chunjun_undefine.sv" 
